package com.alibaba.citrus.ots.application.report.ability.facade.service;

import com.alibaba.citrus.ots.application.report.ability.repository.PlatformRepository;
import com.alibaba.citrus.ots.application.report.ability.utils.DomUtil;
import com.alibaba.citrus.ots.application.report.ability.utils.SubtotalViewVOUtil;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Response;
import com.epoch.app.bcorder.model.dto.ListPlatformPageReportRequest;
import com.epoch.app.bcorder.model.dto.ListPlatformPageReportResponse;
import com.epoch.app.bcorder.model.dto.OrganizationSDO;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.otsapplicationreportsdk.contants.OtsApplicationReportSdkConstants;
import com.epoch.app.otsapplicationreportsdk.model.dto.IncomeCompletionProgressResponse;
import com.epoch.app.otsapplicationreportsdk.model.dto.InvoiceAllocateReportCount;
import com.epoch.app.otsapplicationreportsdk.model.dto.SubtotalViewVO;
import com.epoch.app.otsapplicationreportsdk.oarsinvoiceallocatereportindex.dto.QueryInvoiceAllocateRequest;
import com.epoch.app.otsapplicationreportsdk.oarsinvoiceallocatereportindex.dto.QueryInvoiceAllocateResponse;
import com.epoch.app.otsapplicationreportsdk.oarsinvoiceallocatereportindex.dto.QueryInvoiceDataRequest;
import com.epoch.app.otsapplicationreportsdk.oarsinvoiceallocatereportindex.model.OarsInvoiceAllocateReportIndex;
import com.epoch.app.otsapplicationreportsdk.oarsinvoiceallocatereportindex.service.OarsInvoiceAllocateReportIndexService;
import com.epoch.app.otsapplicationreportsdk.oarswmsorderallocateorderreport.service.OarsWmsOrderAllocateOrderReportService;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class OarsInvoiceAllocateReportIndexServiceImpl implements OarsInvoiceAllocateReportIndexService {
    public final static  String ORG_CODE = "1900021273"; //电商销售组织


    private static Log log = Log.getLogger(OarsInvoiceAllocateReportIndexServiceImpl.class);
    // private final static Logger log= LoggerFactory.getLogger(IncomeCompletionProgressReportServiceImpl.class);
    @Resource
    OarsWmsOrderAllocateOrderReportService oarsWmsOrderAllocateOrderReportService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private BcOrderService bcOtsService;

    @Resource
    private CrUnifiedInventoryService otsUnifiedInventoryService;


    @Resource
    private PlatformRepository platformRepository;
    @Override
    public QueryInvoiceAllocateResponse queryInvoiceAllocate(QueryInvoiceAllocateRequest queryInvoiceAllocateRequest){
        log.info("净收达成入参："+ JSONObject.toJSONString(queryInvoiceAllocateRequest));
        QueryInvoiceAllocateResponse queryInvoiceAllocateResponse = new QueryInvoiceAllocateResponse();
// 如果查询条件没有传电商平台 则查询所有电商平台
        if (CollectionUtils.isEmpty(queryInvoiceAllocateRequest.getPlatformCodes())) {
            List<String> allPlatFormIds = new ArrayList<>(platformRepository.getWarehouseByPlatFormCodes());
            queryInvoiceAllocateRequest.setPlatformCodes(allPlatFormIds);
        }


        // 默认查当天
        Date startTime = DateUtils.getFirstTime(new Date());
        Date endTime = DateUtils.getLatestTime(new Date());
        if (CollectionUtils.isNotEmpty(queryInvoiceAllocateRequest.getTime())) {
            startTime = DateUtils.getFirstTime(DateUtils.toDateStr(DateUtils.parse(queryInvoiceAllocateRequest.getTime().get(0).toString()), DateUtils.DATETIME_FORMAT));
            endTime = DateUtils.getLastTime(DateUtils.toDateStr(DateUtils.parse(queryInvoiceAllocateRequest.getTime().get(1).toString()), DateUtils.DATETIME_FORMAT));
            queryInvoiceAllocateRequest.setTime(Arrays.asList(startTime, endTime));
        }

        // 分页查询 电商平台
        ListPlatformPageReportRequest reportRequest = ListPlatformPageReportRequest.builder()
                .start(queryInvoiceAllocateRequest.getStart())
                .limit(queryInvoiceAllocateRequest.getLimit())
                .platformIds(queryInvoiceAllocateRequest.getPlatformCodes())
                .build();
        ListPlatformPageReportResponse listPlatformPageReportResponse = bcOtsService.listPlatformPageReport(reportRequest);
        List platformList = new ArrayList();
        if (Objects.nonNull(listPlatformPageReportResponse) && CollectionUtils.isNotEmpty(listPlatformPageReportResponse.getResult())) {
            platformList = listPlatformPageReportResponse.getResult();
        }
        // 分页查询 电商平台 ids
        List<String> platformCodes = new ArrayList<>();
        platformList.forEach(o -> {
            Map map = (Map) o;
            platformCodes.add(map.get("platformCode").toString());
        });
        log.info("查询得到电商平台code："+JSONObject.toJSONString(platformCodes));

        //增加其他电商平台
        if (queryInvoiceAllocateRequest.getPlatformCodes().contains(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())
                || CollectionUtils.isEmpty(queryInvoiceAllocateRequest.getPlatformCodes())) {
            platformCodes.add(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
            platformList.add(new HashMap<String, String>() {{
                put("platformCode", OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
                put("platformName", OtsApplicationReportSdkConstants.OTHER_PLATFORM_NAME());
            }});
        }

        // 拉取所有符合要求的调拨单
        List<InvoiceAllocateReportCount> allocateOrderList = getAllocateOrderList(platformCodes,DateUtils.getFirstTime(startTime),DateUtils.getLatestTime(endTime));

        // 分页查询 电商平台：送货目标已达成数
        //Map<String, Long> map = platDeliverTargetReached(allocateOrderList);
        Map<String, Long> map = allocateOrderList.stream().collect(Collectors.toMap(InvoiceAllocateReportCount::getPlatformId, InvoiceAllocateReportCount::getReachNum, (key1, key2) -> key2));

//        if(map.get(null)){
//            String platform = StringUtils.isEmpty(invoice.getAddressCommercePlatform())?OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID():invoice.getAddressCommercePlatform();
//        }
        log.info("组装数据后结果："+JSONObject.toJSONString(map));

        // 最终返回结果
        List<IncomeCompletionProgressResponse> list = new ArrayList<>();
        platformList.forEach(x -> {
            Map platformMap = (Map) x;
            IncomeCompletionProgressResponse incomeCompletionProgressResponse = new IncomeCompletionProgressResponse();
            incomeCompletionProgressResponse.setPlatformName(platformMap.get("platformName").toString());
//            incomeCompletionProgressResponse.setDeliveryTarget(incomeCompletionProgress.getDeliveryTarget());
//            incomeCompletionProgressResponse.setDeliveryTargetAchievementRate(incomeCompletionProgress.getDeliveryTargetAchievementRate());
//            incomeCompletionProgressResponse.setSalesForecast(incomeCompletionProgress.getSalesForecast());
//            incomeCompletionProgressResponse.setSalesForecastReached(incomeCompletionProgress.getSalesForecastReached());
//            incomeCompletionProgressResponse.setEstimatedSalesAchievementRate(incomeCompletionProgress.getEstimatedSalesAchievementRate());
            // 送货目标已达成
            incomeCompletionProgressResponse.setDeliveryTargetReached(DomUtil.numFormat2(map.get(platformMap.get("platformCode")),queryInvoiceAllocateRequest.getIsExcel()));
            list.add(incomeCompletionProgressResponse);
        });

        // 表头数据查询
        // 统计 不分页查询 符合要求的调拨单
//        List<OarsWmsOrderAllocateOrderReport> allocateOrderListTotal = getAllocateOrderList(platformCodesById(queryInvoiceAllocateRequest.getPlatformCodes()),
//                DateUtils.getFirstTime(startTime),
//                DateUtils.getLatestTime(endTime));
        // 不分页查询 电商平台：送货目标已达成数
        //Map<String, Long> mapTotal = platDeliverTargetReached(allocateOrderListTotal);
        // 判断如果是最后一页 加一个统计
        if (listPlatformPageReportResponse.getTotal() > (queryInvoiceAllocateRequest.getStart() - 1) * queryInvoiceAllocateRequest.getLimit()
                && listPlatformPageReportResponse.getTotal() >= queryInvoiceAllocateRequest.getStart() * queryInvoiceAllocateRequest.getLimit()) {
            IncomeCompletionProgressResponse incomeCompletionProgressResponse = new IncomeCompletionProgressResponse();
            Long s = map.values().stream().mapToLong(o -> o).sum();
            incomeCompletionProgressResponse.setPlatformName("总计：" + DomUtil.numFormat2(s,queryInvoiceAllocateRequest.getIsExcel()) + "件");
            list.add(incomeCompletionProgressResponse);
        }
        Long totalValue = DomUtil.divide(map.values().stream().mapToLong(o -> o).sum(), 1);

        // 表头数据组装
        SubtotalViewVO subtotalVODeltaNoFormat = SubtotalViewVOUtil.getSubtotalVODeltaNoFormat("送货目标已达成", "件",new BigDecimal(totalValue));
        Result<List<IncomeCompletionProgressResponse>> listResult1 = Result.listSuccess(list, platformCodes.size());
        listResult1.setExt(new HashMap<String, Object>() {{
            put("statistic", Arrays.asList(SubtotalViewVO.builder().label("送货目标").value("-").build(), subtotalVODeltaNoFormat));
        }});


        castInvoiceResponse(queryInvoiceAllocateResponse, listResult1);
        return queryInvoiceAllocateResponse;

    }

    private void castInvoiceResponse(QueryInvoiceAllocateResponse queryInvoiceAllocateResponse, Result<List<IncomeCompletionProgressResponse>> listResult1) {
        queryInvoiceAllocateResponse.setResult(listResult1.getResult());
        queryInvoiceAllocateResponse.setExt(listResult1.getExt());
        queryInvoiceAllocateResponse.setExtData(listResult1.getExt());
        queryInvoiceAllocateResponse.setSuccess(listResult1.isSuccess());
        queryInvoiceAllocateResponse.setTotal(listResult1.getTotal());
    }

    /**
     * 获取 符合要求的调拨单
     *
     * @param platformIds
     * @param startTime
     * @param endTime
     * @return
     */
    @FacadeInvoker
    private List<InvoiceAllocateReportCount> getAllocateOrderList(List<String> platformIds, Date startTime, Date endTime) {
        // 【调拨类型：总部销售调拨单】；【是否是直发客户：是】；【提报组织：1900021273】

        // 查询 1900021273 收货组织下的
        OrganizationSDO organizationSDO = allocateOrderByCode(ORG_CODE);
        if (ObjectUtils.isEmpty(organizationSDO)) {
            return new ArrayList<>();
        }

        int limit = 500;
        int start = 0;
        QueryInvoiceDataRequest request = QueryInvoiceDataRequest.builder()
                .platformNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())
                .type(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType())
                .isDTC(1)
                .applyOrgIds(Arrays.asList(organizationSDO.getId()))
                .warehouseTypes(Arrays.asList(2, 5))
                .platformIds(platformIds)
                .startTime(startTime)
                .endTime(endTime)
                .start(start)
                .limit(limit)
                .build();
        Result<List<InvoiceAllocateReportCount>> totalResult = queryInvoiceData(request);

        if (ObjectUtils.isEmpty(totalResult.getResult())) {
            log.info("没有符合要求的调拨单，入参：{}", JSON.toJSONString(request));
            return new ArrayList<>();
        }
        List<InvoiceAllocateReportCount> result = totalResult.getResult();
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(result)){
            for (InvoiceAllocateReportCount invoiceAllocateReportCount : result) {
                if (org.apache.commons.lang3.StringUtils.isBlank(invoiceAllocateReportCount.getPlatformId())){
                    invoiceAllocateReportCount.setPlatformId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
                }
            }
        }

       /* int total = totalResult.getTotal();
        int allPage = total / limit;
        if (total % limit > 0) {
            allPage++;
        }

        for (int i = 1; i < allPage; i++) {
            start = i * limit;
            request.setStart(start);
            log.info("getAllocateOrderList_request：{}", JSON.toJSONString(request));
            Result<List<InvoiceAllocateReportCount>> listResult1 = queryInvoiceData(request);
            if (!ObjectUtils.isEmpty(listResult1) && !CollectionUtils.isEmpty(listResult1.getResult())) {
                result.addAll(listResult1.getResult());
            }
        }*/

        return result;
    }

    /**
     * 根据 code 查询 组织
     *
     * @param code
     * @return
     */
    private OrganizationSDO allocateOrderByCode(String code) {
        BaselineGetOrganizationByOutCodes2Request request = BaselineGetOrganizationByOutCodes2Request.builder().outCodes(Collections.singletonList(code)).build();
        BaselineGetOrganizationByOutCodes2Response res =
                baseDataService.baselineGetOrganizationByOutCodes2(request);
        if (ObjectUtils.isEmpty(res)) {
            return null;
        }
        List<OrganizationSDO> result = res.getResult();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(result)) {
            return null;
        }
        return result.get(0);
    }

    /**
     * 获取 电商平台：送货目标已达成
     *
     * @param list
     * @return
     */
    private Map<String, Long> platDeliverTargetReached(List<OarsInvoiceAllocateReportIndex> list) {
        Map<String, Long> map = new HashMap<>();

        list.forEach(invoice -> {
            // 数量
            Long wmsGoodsQuantity = Long.parseLong(invoice.getInvoiceQuantity());
            // 调拨单退单类型 0 不是 1 是
            Long allocateOrderReturnOrder = invoice.getAllocateReturnOrder();

            // 电商平台id
            String platform = StringUtils.isEmpty(invoice.getAddressCommercePlatform())?OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID():invoice.getAddressCommercePlatform();

            Long value = map.get(platform) == null ? 0L : map.get(platform);
            if (!ObjectUtils.isEmpty(allocateOrderReturnOrder) && allocateOrderReturnOrder == 1) {
                // 退单调拨单 出库数量累加值
                // 出库
                value -= wmsGoodsQuantity;
            } else {
                // 正向调拨单 入库数量累加值
                // 入库
                value += wmsGoodsQuantity;
            }
            map.put(platform, value);
        });
        return map;
    }



}
